/*
 * Copyright (C) 2003, Velocityme Partnership
 * ChangeDeltaBean.java
 *
 * Created on 26 March 2003, 10:22
 */

package com.velocityme.entity;

import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import com.velocityme.interfaces.*;
import com.velocityme.interfaces.ServiceUnavailableException;
import com.velocityme.utility.ChangeDeltaHelper;

/**
 * This class is used to represent a single change delta for any object extending
 * DBObject.
 *
 * @author  Robert Crida Work
 * @version $Revision: 796 $
 *
 * @ejb.bean
 *           type="CMP"
 *           cmp-version="2.x"
 *           name="ChangeDelta"
 *           jndi-name="ejb/ChangeDelta"
 *           view-type="local"
 * @ejb.transaction type="Required"
 *
 * @ejb.value-object match="*"
 *
 * @ejb.persistence table-name="changedelta"
 *
 * @ejb.util generate="physical"
 *
 * @ejb.finder signature="java.util.Collection findChangeDeltaByType(com.velocityme.interfaces.DBObjectLocal p_object, com.velocityme.interfaces.ChangeDeltaTypeLocal p_type)"
 *              query="SELECT DISTINCT OBJECT(c) FROM ChangeDelta c WHERE c.dBObjectLocal = ?1 AND c.changeDeltaTypeLocal = ?2" 
 *
 * @jboss.persistence create-table="true"
 *                    remove-table="false"
 **/
public abstract class ChangeDeltaBean implements EntityBean {

    /**
    * Context set by container
    */
    protected javax.ejb.EntityContext m_entityContext;
   
    public void setEntityContext(javax.ejb.EntityContext entityContext) {
        m_entityContext = entityContext;
    }

    public void unsetEntityContext() {
        m_entityContext = null;
    }

    /** @ejb.create-method */
    public com.velocityme.interfaces.ChangeDeltaPK ejbCreate(java.util.Date p_date,
                                                             int p_changeDeltaTypeId,
                                                             com.velocityme.interfaces.UserLocal p_userLocal,
                                                             com.velocityme.interfaces.DBObjectLocal p_dBObjectLocal) throws CreateException, EJBException {
        try {
            setChangeDeltaId(generateNewID());
        }
        catch(ServiceUnavailableException e) {
            throw new EJBException(e.getMessage());
        }
        // EJB 2.0 spec says return null for CMP ejbCreate methods.
        return null;
    }

    public void ejbPostCreate(java.util.Date p_date,
                              int p_changeDeltaTypeId,
                              com.velocityme.interfaces.UserLocal p_userLocal,
                              com.velocityme.interfaces.DBObjectLocal p_dBObjectLocal) throws CreateException, java.rmi.RemoteException {
        // CMR relations must be set in ejbPostCreate
        setDate(p_date);
        setChangeDeltaTypeLocal(ChangeDeltaHelper.getInstance().getDeltaTypeLocal(p_changeDeltaTypeId));
        setUserLocal(p_userLocal);
        setDBObjectLocal(p_dBObjectLocal);
    }

    /**
     * Retrive a unique creation id to use for this bean.  This will end up
     * demarcating this bean from others when it is stored as a record
     * in the database.
     *
     * @return Returns an integer that can be used as a unique creation id.
     *
     * @throws ServiceUnavailableException Indicating that it was not possible
     *                                     to retrieve a new unqiue ID because
     *                                     the service is not available
     **/
    private Integer generateNewID() throws ServiceUnavailableException {
        int lUniqueId = -1;
        try {            
            SequenceGenerator lBean = SequenceGeneratorUtil.getHome().create();
            lUniqueId = lBean.getNextNumber("changedelta","changeDeltaId");
            lBean.remove();
        }
        catch ( NamingException ne ) {
            throw new ServiceUnavailableException( "Naming lookup failure: " + ne.getMessage() );
        }
        catch ( CreateException ce ) {
            throw new ServiceUnavailableException( "Failure while creating a generator session bean: " + ce.getMessage() );
        }
        catch ( RemoveException re ) {
            // When the Bean cannot be removed after a while it will be taken back by the container
            // therefore ignore this exception
        }
        catch ( RemoteException rte ) {
            throw new ServiceUnavailableException( "Remote exception occured while accessing generator session bean: " +  rte.getMessage() );
        }
        
        return new Integer(lUniqueId);
    }
    
    /**
     *  This gets a local object from a remote object.
     *  @ejb.interface-method view-type="remote"
     */
    public com.velocityme.interfaces.ChangeDeltaLocal getLocal() {
        return (ChangeDeltaLocal)m_entityContext.getEJBLocalObject();
    }
    
    /** @ejb.interface-method view-type="local" */
    public abstract com.velocityme.valueobjects.ChangeDeltaValue getChangeDeltaValue();

    //=======================================================================
    //
    //                   ATTRIBUTES
    //
    //=======================================================================
      
    /**
     * @ejb.persistence column-name="changeDeltaId"
     * @ejb.interface-method view-type="local"
     * @ejb.pk-field
     */
    public abstract java.lang.Integer getChangeDeltaId();
    /** @ejb.interface-method view-type="local" */
    public abstract void setChangeDeltaId(java.lang.Integer changeDeltaId);

    /**
     * @ejb.persistence column-name="date"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getDate();
    /** @ejb.interface-method view-type="local" */
    public abstract void setDate(java.util.Date date);
    
    //=======================================================================
    //
    //                   RELATIONSHIPS
    //
    //=======================================================================
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="ChangeDelta-ChangeDeltaType"
     *               role-name="ChangeDelta-has-a-ChangeDeltaType"
     *               target-ejb="ChangeDeltaType"
     *               target-role-name="ChangeDeltaType-has-many-ChangeDeltas"
     *               target-multiple="yes"
     * @jboss.relation fk-column="changeDeltaTypeIdFk"
     *                 related-pk-field="changeDeltaTypeId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.ChangeDeltaTypeValue"
     *                   aggregate-name="ChangeDeltaTypeValue"
     */
    public abstract com.velocityme.interfaces.ChangeDeltaTypeLocal getChangeDeltaTypeLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setChangeDeltaTypeLocal(com.velocityme.interfaces.ChangeDeltaTypeLocal type);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="ChangeDelta-User"
     *               role-name="ChangeDelta-has-a-User"
     *               target-ejb="User"
     *               target-role-name="User-has-many-ChangeDeltas"
     *               target-multiple="yes"
     * @jboss.relation fk-column="userdFk"
     *                 related-pk-field="userId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.UserValue"
     *                   aggregate-name="UserValue"
     */
    public abstract com.velocityme.interfaces.UserLocal getUserLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setUserLocal(com.velocityme.interfaces.UserLocal user);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="DBObject-ChangeDelta"
     *               role-name="ChangeDelta-has-a-DBObject"
     * @jboss.relation fk-column="dBObjectIdFk"
     *                 related-pk-field="dBObjectId"
     */
    public abstract com.velocityme.interfaces.DBObjectLocal getDBObjectLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setDBObjectLocal(com.velocityme.interfaces.DBObjectLocal dbObject);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="FileAttachment-ChangeDelta"
     *               role-name="ChangeDelta-may-have-a-FileAttachment"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.FileAttachmentValue"
     *                   aggregate-name="FileAttachmentValue"
     */
    public abstract com.velocityme.interfaces.FileAttachmentLocal getFileAttachmentLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setFileAttachmentLocal(com.velocityme.interfaces.FileAttachmentLocal p_fileAttachment);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="ChangeDeltaItem-ChangeDelta"
     *               role-name="ChangeDelta-has-many-ChangeDeltaItems"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.ChangeDeltaItemValue"
     *                   aggregate-name="ChangeDeltaItemValue"
     *                   members="com.velocityme.interfaces.ChangeDeltaItemLocal"
     *                   members-name="ChangeDeltaItemLocal"
     *                   relation="external"
     *                   type="Collection"
     */
    public abstract java.util.Collection getChangeDeltaItemsLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setChangeDeltaItemsLocal(java.util.Collection changeDeltaItemsLocal);
    
    //=======================================================================
    //
    //                   MANAGEMENT METHODS
    //
    //=======================================================================
    
    /**
     *  @ejb.interface-method view-type="local"
     */
    public void addItem(int p_changeDeltaItemTypeId, java.lang.String p_description) {
        try {
            ChangeDeltaItemUtil.getLocalHome().create(getLocal(), ChangeDeltaHelper.getInstance().getItemTypeLocal(p_changeDeltaItemTypeId), p_description);
        } catch(NamingException e) {
            throw new EJBException(e);
        } catch(CreateException e) {
            throw new EJBException(e);
        }
    }

}
